#include "FrontLampStateMachine.h"
#include "FrontLampNormalState.h"
#include "F3LampInterfaces.h"
#include "LampManager.h"

void InitFrontStateMachine(void)
{
    InitFrontLampSleepStateMachine();
    InitFrontNormalStateMachine();
    InitRibbonLoBeamStateMachine();
}

static void exitLastState(UsageModeState lastState)
{
    switch (lastState)
    {
        case UsageModeState_Normal:
        {
            g_FrontNormalStateMachine.sm_.Exit();
            break;
        }

        case UsageModeState_Ribbon:
        {
            g_RibbonLoBeamStateMachine.sm_.Exit();
            break;
        }

        case UsageModeState_Sleep:
        {
            g_FrontLampSleepStateMachine.sm_.Exit();
            break;
        }

        default:
            break;
    }
}

static void entryNewState(UsageModeState newState)
{
    switch (newState)
    {
        case UsageModeState_Normal:
        {
            g_FrontNormalStateMachine.sm_.Entry();
            break;
        }

        case UsageModeState_Ribbon:
        {
            g_RibbonLoBeamStateMachine.sm_.Entry();
            break;
        }

        case UsageModeState_Sleep:
        {
            g_FrontLampSleepStateMachine.sm_.Entry();
            break;
        }

        default:
            break;
    }
}

static void excuteNewState(UsageModeState newState)
{
        switch (newState)
    {
        case UsageModeState_Normal:
        {
            g_FrontNormalStateMachine.sm_.Excute();
            break;
        }

        case UsageModeState_Ribbon:
        {
            g_RibbonLoBeamStateMachine.sm_.Excute();
            break;
        }

        case UsageModeState_Sleep:
        {
            g_FrontLampSleepStateMachine.sm_.Excute();
            break;
        }

        default:
            break;
    }
}

void FrontStateMachineExecute(void)
{
    if(g_FrontNewState.usageModeState_ != g_FrontLastState.usageModeState_)
    {
        exitLastState(g_FrontLastState.usageModeState_);
        entryNewState(g_FrontNewState.usageModeState_);
    }

    excuteNewState(g_FrontNewState.usageModeState_);
}

void FrontSleepStateTransition(void)
{

}

void FrontNormalStateTransition(void)
{
    // Front lamp normal state ignore any child state
}

static void calculateLobeamShowEffect(void)
{
    RibbonEffectSel show = Get_CANSIG_LoBeamEffectSel();
    g_RibbonView.model_->loBeamEffectSt_ = show;
    switch(show)
    {
        case RibbonEffect_Effect_2:
        {
                g_FrontNewState.ribbonLobeamEffectShowState_ = RibbonLobeamEffectShowState_Unlock;
                break;
        }

        case RibbonEffect_Effect_8:
        {
                g_FrontNewState.ribbonLobeamEffectShowState_ = RibbonLobeamEffectShowState_Lock;
                break;
        }
        default:
        {
                g_FrontNewState.ribbonLobeamEffectShowState_ = RibbonLobeamEffectShowState_Default;
                break;
        }
    }
}

static void RibbonLoBeamStateTransition(bool turnLampOccupy, RibbonCtrlCmd cmd)
{
    if(turnLampOccupy)
    {
            g_FrontNewState.ribbonLobeamCtrlState_ = RibbonLobeamCtrlState_Again;
    }
    else
    {
        switch(cmd)
        {
            case RibbonCtrl_Initial:
            case RibbonCtrl_NoRequest:
            {
                //Ignore
                break;
            }
            case RibbonCtrl_Off:
            case RibbonCtrl_Invalid:
            {
                g_FrontNewState.ribbonLobeamCtrlState_ = RibbonLobeamCtrlState_Off;
                break;
            }

            case RibbonCtrl_On:
            case RibbonCtrl_Pause:
            {
                g_FrontNewState.ribbonLobeamCtrlState_ = RibbonLobeamCtrlState_On;
                calculateLobeamShowEffect();
                break;
            }

            case RibbonCtrl_Again:
            {
                g_FrontNewState.ribbonLobeamCtrlState_ = RibbonLobeamCtrlState_Again;
                break;
            }

            default:
            {
                g_FrontNewState.ribbonLobeamCtrlState_ = RibbonLobeamCtrlState_Off;
                break;
            }
        }
    }

}

static void calculateRobbinLoBeamAnimationModel(RibbonCtrlCmd loBeamCtrlcmd)
{
    if(loBeamCtrlcmd == RibbonCtrl_Pause)
    {
        g_RibbonAnimationModel.lobeamMode_ = Pause;
    }
    else
    {
        RibbonEffectMod mode = Get_CANSIG_FrntRibbonLampEffectModSet();
        switch(mode)
        {
            case RibbonEffectMod_Initial:
            {
                g_RibbonAnimationModel.lobeamMode_ = Pause;   // Init action as Pause
                break;
            }

            case RibbonEffectMod_Off:
            case RibbonEffectMod_Hold:
            {
                g_RibbonAnimationModel.lobeamMode_ = Hold;    // Off action as Hold
                break;
            }

            case RibbonEffectMod_Repeat:
            {

                g_RibbonAnimationModel.lobeamMode_ = Repeat;
                break;
            }

            default:
            {
                g_RibbonAnimationModel.lobeamMode_ = Default; //Unknown
                break;
            }

        }
    }
}

void FrontRibbonStateTransition(void)
{
    TurnLampOccupyStsFlag turnLampFlag = Get_CANSIG_TurnLampOccupySts();
    bool turnLampOccupy = turnLampFlag == TurnLampOccupySts_LeTurn || turnLampFlag == TurnLampOccupySts_ALL || Is_TL_EN();
    RibbonCtrlCmd loBeamCtrlcmd = Get_CANSIG_LoBeamEffectCtrlCmd();
    RibbonLoBeamStateTransition(turnLampOccupy, loBeamCtrlcmd);
    calculateRobbinLoBeamAnimationModel(loBeamCtrlcmd);
}
